#include <string.h>
#include <unistd.h>

#include <fstream>
#include <thread>
#include <iostream>
#include <string>

#include "cJSON.h"
#include "zmq.h"

using namespace std;

#define FrameSize  6*1024*1024
#define PARAM_SIZE 1024
int g_cnt = 0;

typedef struct Model
{
    char param[PARAM_SIZE];
    char data[FrameSize];
}Model;


void CntThread()
{
    int curCnt = g_cnt;
    while(1)
    {
        curCnt = g_cnt;
        sleep(1);
        cout << "recv " << g_cnt - curCnt << " FPS" << endl;
    }
}

//发布订阅模型，订阅者
int subscriber()
{
    printf("Hello world!\n");
 
    void* context = zmq_ctx_new();
    void* subscriber = zmq_socket(context, ZMQ_SUB);

      /* 修改socket 的收发缓冲区大小为 32M bytes */
    // int sendbuff = 32*1024*1024;
    // zmq_setsockopt(subscriber, ZMQ_SNDBUF, (void *)&sendbuff, sizeof(int));
    // int recvbuff = 32*1024*1024;
    // zmq_setsockopt(subscriber, ZMQ_RCVBUF, (void *)&recvbuff, sizeof(int));

    int ret = zmq_connect(subscriber, "tcp://localhost:5558");
 
    ret = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);//接收所有消息.不过滤消息

    char szBuf[FrameSize] = {0};

    thread t1(CntThread);
 
    while(1)
    {
        ret = zmq_recv(subscriber, szBuf, FrameSize, 0);
        //char buf[sizeof(Model)] = {0} ;
        //ret = zmq_recv(subscriber, buf, sizeof(Model), 0);
        if (ret < 0)
        {
            printf("recv fail\n");
        }
        else
        {
            //printf("recv data len : %d   no: %d\n", ret, model->no);
            printf("recv data len : %d \n", ret);
        }
        g_cnt++;
    }
 
    zmq_close(subscriber);
    zmq_ctx_destroy(context);


 
    return 0;
}


//推拉模型，puller
// int puller()
// {
//     printf("Hello world!\n");
 
//     void* context = zmq_ctx_new();
//     void* puller = zmq_socket(context, ZMQ_PULL);

//     int ret = zmq_connect(puller, "tcp://localhost:5558");
 
//     char szBuf[FrameSize] = {0};

//     thread t1(CntThread);
 
//     while(1)
//     {
        
//         ret = zmq_recv(puller, szBuf, FrameSize, 0);//接收数据
//         if (ret < 0)
//         {
//             printf("recv fail\n");
//         }
//         else
//         {
//             printf("recv data len : %d \n", ret);

//             //拿param部分数据(json格式字符串)
//             char param[PARAM_SIZE];
//             memcpy(param, szBuf, PARAM_SIZE);
//             cJSON *root;
//             root = cJSON_Parse(param);
//             char *out = cJSON_Print(root);
//             printf("%s\n", out);
            
//             //拿YUV数据
//             char* yuvData = szBuf + PARAM_SIZE;
//             cJSON *data_size_json = cJSON_GetObjectItem(root, "data_size");
//             int data_size = data_size_json->valueint;
//             printf("data_size %d \n", data_size);

//             //将YUV数据写入本地文件
//             fstream ofs("out.png", ios::out | ios::binary);
//             ofs.write(yuvData, data_size);

//             free(out);
//             cJSON_Delete(root);
//         }

//         g_cnt++;
//     }
 
//     zmq_close(puller);
//     zmq_ctx_destroy(context);

//     return 0;
// }

int puller()
{
    printf("Hello world!\n");
 
    void* context = zmq_ctx_new();
    void* puller = zmq_socket(context, ZMQ_PULL);

    int ret = zmq_connect(puller, "tcp://localhost:6555");
 
    char szBuf[FrameSize] = {0};

    thread t1(CntThread);
 
    while(1)
    {
        
        ret = zmq_recv(puller, szBuf, FrameSize, 0);//接收数据
        if (ret < 0)
        {
            printf("recv fail\n");
        }
        else
        {
            //printf("recv data len : %d \n", ret);

            //数据总长度
            int totalLen = 0;
            memcpy(&totalLen, szBuf, 4);

            //json数据长度
            int jsonDataLen = 0;
            memcpy(&jsonDataLen, szBuf + 4, 4);

            //图像数据长度
            int imgDataLen = 0;
            memcpy(&imgDataLen, szBuf + 8, 4);

            //printf("toalLen = %d\n", totalLen);
            //printf("jsonDataLen = %d\n", jsonDataLen);
            //printf("imgDataLen = %d\n", imgDataLen);

            //拿param部分数据(json格式字符串)
            char param[jsonDataLen];
            memcpy(param, szBuf + 12, jsonDataLen);
            cJSON *root;
            root = cJSON_Parse(param);
            char *out = cJSON_Print(root);
            //printf("%s\n", out);
            
            //拿YUV数据
            //char* yuvData = (char*)malloc(imgDataLen);
            //memcpy(yuvData, szBuf + 12 + jsonDataLen, imgDataLen);

            //将YUV数据写入本地文件
            //fstream ofs("out.rgb", ios::out | ios::binary);
            //ofs.write(yuvData, imgDataLen);

            //free(yuvData);
            free(out);
            cJSON_Delete(root);
        }

        g_cnt++;
    }
 
    zmq_close(puller);
    zmq_ctx_destroy(context);

    return 0;
}


int main()
{
    puller();

    return 0;
}
